﻿using System.IO;
using System;
using System.Collections.Generic;

using System.Text;

namespace xReplace
{
    class ReplaceCommand:AbstractProcessingCommand
    {

        public ReplaceCommand(ref Content pipes)
            : base(ref pipes)
        {}

        public override bool ProcessCommand(System.Xml.XmlNodeList param)
        {

            string fromLabel = GetNodeValue("fromlabel", param);
            string toLabel = GetNodeValue("tolabel", param);
            string startsWith = GetNodeValue("startswith", param);
            string endsWith = GetNodeValue("endswith", param);
            string src = GetNodeValue("match", param);
            string srcChars = GetNodeValue("matchchars", param);
            string dest = GetNodeValue("replacewith", param);
            string destLabel = GetNodeValue("replacewithlabel", param);
            string templateFilename = GetNodeValue("filename", param);
            string skipStart = GetNodeValue("skipstart", param);
            string skipEnd = GetNodeValue("skipend", param);
            string renameRules = this.GetNodeValue("renamerules", param);
            string ignoreCaseStr = GetNodeValue("ignorecase", param);
            bool ignoreCase = (ignoreCaseStr.ToLower() == "true") ? true : false;

            if (GetNodeAttributeAsBoolean("matchchars", "escape", param))
                srcChars = SpecialCharHelper.Unescape(srcChars);
            if (GetNodeAttributeAsBoolean("startswith", "escape", param))
                startsWith= SpecialCharHelper.Unescape(startsWith);
            if (GetNodeAttributeAsBoolean("endswith", "escape", param))
                endsWith = SpecialCharHelper.Unescape(endsWith);
            if (GetNodeAttributeAsBoolean("match", "escape", param))
                src= SpecialCharHelper.Unescape(src);
            if (GetNodeAttributeAsBoolean("replacewith", "escape", param))
                dest = SpecialCharHelper.Unescape(dest);

            if (destLabel != "") dest = contentPipelines.LoadContent(destLabel);
            if ((templateFilename != "") && (this.NodeExists("filename", param)))
            {
                if (renameRules != "")
                    templateFilename = RenameHelper.PerformRename(templateFilename, renameRules, this.contentPipelines);
                dest = File.ReadAllText(templateFilename);
            }
            
            fromLabel = (fromLabel == "") ? Content.DEFAULT_KEY : fromLabel;
            toLabel = (toLabel == "") ? Content.DEFAULT_KEY : toLabel;
            string tmp = contentPipelines.LoadContent(fromLabel);
            if ((src != "") && (startsWith == "") && (endsWith == ""))
            {
                tmp = tmp.Replace(src, dest);
            }
            else if ((srcChars != "") && (startsWith == "") && (endsWith == ""))
            {
                char[] items = srcChars.ToCharArray();
                for (int x = 0; x < items.Length; x++)
                {
                    tmp = tmp.Replace(items[x].ToString(), dest);
                }
            }
            else
            {

                TextFragment frag = new TextFragment(tmp);
                while (frag.GrabFragment(startsWith,endsWith,skipStart,skipEnd,ignoreCase))
                {
                    if ((src == "") && (srcChars == ""))
                    {
                        tmp = tmp.Replace(frag.Fragment, dest);
                    }
                    else if(src != "")
                    {
                        tmp = tmp.Replace(frag.Fragment, frag.Fragment.Replace(src, dest));
                    }
                    else if (srcChars != "")
                    {
                        char[] items = srcChars.ToCharArray();
                        string buf = frag.Fragment;
                        for (int x = 0; x < items.Length; x++)
                        {
                            buf = buf.Replace(items[x].ToString(), dest);
                        }
                        tmp = tmp.Replace(frag.Fragment, buf);
                    }
                    if ((startsWith == "") && (endsWith == "")) break;
                }
            }
            contentPipelines.StoreContent(toLabel, tmp);
            return true;
        }

    }
}
